1. Field of the Invention
The present invention relates generally to a data processing system. More specifically, the present invention relates to a computer implemented method, computer program product and data processing system for executing an application written in a dynamic language.
2. Description of the Related Art
The Internet is a global network of connected computer networks. Over the last several years, the Internet has grown in significant measure. A large number of computers on the Internet provide information in various forms. Anyone with a computer connected to the Internet can potentially tap into this vast pool of information.
The most wide spread method of providing information over the Internet is via the World Wide Web (the Web). The Web consists of a subset of the computers connected to the Internet; the computers in this subset run Hypertext Transfer Protocol (HTTP) servers (Web servers). The information available via the Internet also encompasses information available via other types of information servers such as GOPHER, WAIS, SMTP (simple mail transfer protocol), POPS (Post Office Protocol) and FTP (file transfer protocol).
Information on the Internet can be accessed through the use of a Uniform Resource Locator (URL). A Uniform Resource Locator (URL) uniquely specifies the location of a particular piece of information on the Internet.
Web servers host information in the form of Web pages; collectively the server and the information hosted are referred to as a Web site. A significant number of Web pages are encoded using the Hypertext Markup Language (HTML) although other encodings using the eXtensible Markup Language (XML) or the Standard Generic Markup Language (SGML) are becoming increasingly more common. The published specifications for these languages are incorporated by reference herein. Web pages written in these formatting languages may include links to other Web pages on the same Web site or another Web site. As will be known to those skilled in the art, Web pages may be generated dynamically by a server by integrating a variety of elements into a formatted page prior to transmission to a Web client. Web servers, and information servers of other types, await requests for the information from Internet clients.
Client software has evolved that allows users of computers connected to the Internet to access this information. Advanced clients such as Microsoft's Internet Explorer allow users to access software provided via a variety of information servers in a unified client environment (Microsoft is a trademark of Microsoft Corporation in the United States, other countries, or both). Typically, such client software is referred to as browser software.
Client machines connected to the Internet run Web browsers which generally operate by establishing a TCP/IP connection with a server Web site and downloading files written in hyper-text mark-up language (HTML) from the Web site. Java™ enabled browsers running on conventional type personal computers include a Java Virtual Machine (JVM) in which Java byte-code is executed within the browser (Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both).
Java is an object-oriented programming language and environment focusing on defining data as objects and the methods that may be applied to those objects. Java is designed to solve a number of problems in modern programming practice. Java is able to support applications for many types of data processing systems, which may contain a variety of central processing units and operating system architectures. To enable a Java application to execute on different types of data processing systems, a compiler typically generates an architecture-neutral file format, so that the compiled code is executable on many processors, given the presence of the Java runtime system. The Java compiler generates byte code instructions that are non-specific to any particular computer architecture. A byte code is a machine independent code generated by the Java compiler and executed by a Java interpreter. A Java interpreter is a module that alternately decodes and executes a byte code. The decoding of the byte code places the instruction into an executable form for the computer on which the code is to be executed. Then, the instruction is executed by the computer. These byte code instructions are designed to be easy to interpret on any machine and easily translated on the fly into native machine code.
The Java Virtual Machine (JVM) is a virtual computer component. A virtual computer component is an abstract computer component that only resides in memory. A JVM includes components necessary to run a program on a computer, including an interpreter. The JVM allows Java programs to be executed on different platforms as opposed to only a single platform. Typically, computer programs are originally written in a human-readable format called source code, which is then compiled (by a computer program called a “compiler”) into a format that can be directly implemented by a computer system. Conventionally, programs must be compiled for one specific platform (i.e. processing unit and operating system combination), such that a program that has been compiled for one platform will often not run on a different platform. Java programs are compiled for the JVM, rather than for any particular platform (although there are typically different versions of the JVM adapted to different platforms). In this manner, Java is able to support applications for many types of data processing systems, which may contain a variety of central processing units and operating system architectures.
There are a number of approaches to dynamically loading interdependent components of executable code (such as plug-ins, bundles, etc.) in modern programming languages. Dynamically loading means to load one or more components of an application after the application has begun execution. In the Java programming language, classes are dynamically loaded using a class loader as an application program executes. The class loader is responsible for searching for a particular class, and making that class available to the run-time system if found. In object-oriented programming, a class consists of a collection of types of encapsulated instance variables and types of methods, possibly with implementation of those types, together with a constructor function that can be used to create objects of the class. Java class loading is based on a delegation model, wherein a class loader first delegates the class loading responsibility to its immediate parent class loader.
There are a number of limitations inherent in this prior art class loading approach, however. Because the delegation model is linked to Java's single inheritance class structure, a class loader parent chain must be able to load a complete Java type graph. A single inheritance is the ability for a class, the derived class, to inherit from exactly one class, its base class. This necessarily limits subsystems to only one prerequisite, and that prerequisite (and its ancestry) must be able to supply all of the subsystem's ancestor classes, a complex composition of prerequisite components cannot be supported under this approach. In other words, the Java programmer needs to make sure that all type relationships implied in the class implementation, including extended classes, implemented interfaces, declared data member types, argument types of methods, return types of methods, and so forth, can be loaded by the single loader chain of the class. When dealing with complex functional relationships, the programmer typically addresses this problem by adding all the required archives, or “jar” files, on a single long class path. This is a less-than-optimal solution.
Furthermore, components, such as plug-ins, that require a considerable amount of resources, such as storage, to be allocated, take time to be initialized, and will often trigger the loading of many classes once initialized, which consumes more resources and takes additional time. This approach results in an inefficient use of resources in many cases, and increases the start-up time and the memory footprint of the program in which the plug-in is contained. For example, it may happen that some classes are not actually accessed until a relatively long time after activating the plug-in whose initialization triggered loading of the class, and some may never be accessed. These inefficiencies become especially significant in resource-constrained systems.
Other approaches to dynamic class loading, such as OSGi (“Open Services Gateway Initiative”) bundles, use an independent class loader for each component, rather than using the delegation model. However, OSGi bundles do not address the limitations of dynamic class loaders which have been discussed. OSGi bundles continue to rely on parent relationships during loading, and initialize upon start-up as well. The term “OSGi bundles” refers to components which adhere to the OSGi Service Gateway Specification. OSGi bundles are archive files containing class files and resources. A manifest file of a bundle identifies the contents of the bundle and also the packages and services which are imported and exported by that bundle. More information on this specification may be found on the Internet at the OSGi Web site, www.osgi.org. The preceding reference to the OSGi Web site is provided for convenience only and does not in any manner serve as an endorsement by IBM of that Web site. Any use of that Web site may be subject to license conditions and is at your own risk.
Real-time applications cannot tolerate the possibly large delays, on the order of tens (10's) of milliseconds, that can occur if a code segment, for example a Java class, is lazily loaded. Lazily loaded means to delay loading one or more components of an application until the application requires it for execution. Today, there are several options available that are less-than-optimal. One solution is for the user to manage a list of classes themselves and manually load them. Many users do this, but this approach is susceptible to user error. Another approach is for the user to write a simple routine to pre-load all classes in a jar file. This solution loads far more than is necessary. If users want to compile methods of a class at load time, this approach contains too much data and takes a significant amount of time and also uses a significant amount of memory to hold classes that will likely not be referenced. There is also the possibility, as with the first option, that the list of jar files is incomplete. A third solution is to perform a whole program analysis and require that classes can not be dynamically loaded. This solution requires that the program code be a subset of the Java language and this can not be enforced at runtime without restricting the language.
Accordingly, what is needed is an improved technique for dynamically loading independent components referenced code written in a dynamic language at the start of execution instead of lazily, for more deterministic execution time of real-time applications. Independent components are those components whose classes are not necessarily located within a single functional dependence hierarchy.